/*

    This file is part of GLua

    GLua Development Environment
    Copyright (C) 2007 VoiDeD

    GLua is free software; you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.

    GLua is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace GLua
{
    // this control is used to display the object browser
    // it shouldn't really be edited because it's completed
    // but if you want, go ahead
    public partial class ObjectBrowser : UserControl
    {
        CodeProvider code;

        public ObjectBrowser(CodeProvider code, ImageList images)
        {
            InitializeComponent();
            this.code = code;

            treeView1.ImageList = images;
            treeView2.ImageList = images;

            LoadLibs( code );
        }

        private void LoadLibs( CodeProvider code )
        {
            treeView1.Nodes.Clear();

            foreach ( Library lib in code.Libraries )
            {
                TreeNode tn = new TreeNode();
                tn.ImageKey = "library";
                tn.SelectedImageKey = "library";
                tn.Text = lib.Name;
                tn.Tag = lib;
                treeView1.Nodes.Add( tn );
            }
        }

        private void treeView1_AfterSelect( object sender, TreeViewEventArgs e )
        {
            if ( e.Node == null )
                return;

            if ( e.Node.Tag is Library )
            {
                Library lib = ( Library )e.Node.Tag;
                treeView2.Nodes.Clear();

                foreach ( Member memb in lib.Members )
                {
                    TreeNode tn = new TreeNode();
                    LibraryMember lm = new LibraryMember();
                    lm.Library = lib;
                    lm.Member = memb;

                    if ( memb is Function )
                    {
                        Function func = ( Function )memb;
                        tn.Text = func.Name + "(" + func.Params + ")";
                        tn.Tag = lm;
                        switch ( func.Type )
                        {
                            case "SHARED":
                                tn.ImageKey = "shared";
                                tn.SelectedImageKey = "shared";
                                break;
                            case "SERVER":
                                tn.ImageKey = "server";
                                tn.SelectedImageKey = "server";
                                break;
                            case "CLIENT":
                                tn.ImageKey = "client";
                                tn.SelectedImageKey = "client";
                                break;
                        }
                    }
                    else if ( memb is Property )
                    {
                        Property prop = ( Property )memb;
                        tn.Text = prop.Name;
                        tn.Tag = lm;
                        switch ( prop.Type )
                        {
                            case "SHARED":
                                tn.ImageKey = "shared";
                                tn.SelectedImageKey = "shared";
                                break;
                            case "SERVER":
                                tn.ImageKey = "server";
                                tn.SelectedImageKey = "server";
                                break;
                            case "CLIENT":
                                tn.ImageKey = "client";
                                tn.SelectedImageKey = "client";
                                break;
                        }
                    }

                    treeView2.Nodes.Add( tn );

                }

                richTextBox1.Clear();
                richTextBox1.AppendText( "Library " );
                richTextBox1.SelectionFont = new Font( richTextBox1.SelectionFont, FontStyle.Bold );
                richTextBox1.AppendText( lib.Name );
                richTextBox1.SelectionFont = new Font( richTextBox1.SelectionFont, FontStyle.Regular );
                richTextBox1.AppendText( "\n\n" );
                richTextBox1.SelectionFont = new Font( richTextBox1.SelectionFont, FontStyle.Bold );
                richTextBox1.AppendText( "Summary:" );
                richTextBox1.SelectionFont = new Font( richTextBox1.SelectionFont, FontStyle.Regular );
                richTextBox1.AppendText( "\n" + lib.Description );
            }
            else if ( e.Node.Tag is LibraryMember )
            {
                treeView2.Nodes.Clear();
                richTextBox1.Clear();

                LibraryMember lm = ( LibraryMember )e.Node.Tag;
                Library lib = lm.Library;
                Member memb = lm.Member;

                if ( memb is Function )
                {
                    Function func = ( Function )memb;
                    richTextBox1.AppendText( func.Return + " " );
                    richTextBox1.SelectionFont = new Font( richTextBox1.SelectionFont, FontStyle.Bold );
                    richTextBox1.AppendText( lib.Name );
                    richTextBox1.SelectionFont = new Font( richTextBox1.SelectionFont, FontStyle.Regular );
                    richTextBox1.AppendText( "." );
                    richTextBox1.SelectionFont = new Font( richTextBox1.SelectionFont, FontStyle.Bold );
                    richTextBox1.AppendText( func.Name );
                    richTextBox1.SelectionFont = new Font( richTextBox1.SelectionFont, FontStyle.Regular );
                    richTextBox1.AppendText( "(" );
                    string paramText = "";
                    foreach ( Parameter param in func.Parameters )
                    {
                        paramText += param.DataType + " " + param.Name + ", ";
                    }
                    paramText = paramText.TrimEnd( ',', ' ' );
                    richTextBox1.AppendText( paramText + ")\n\n" );
                    richTextBox1.SelectionFont = new Font( richTextBox1.SelectionFont, FontStyle.Bold );
                    richTextBox1.AppendText( "Summary:" );
                    richTextBox1.SelectionFont = new Font( richTextBox1.SelectionFont, FontStyle.Regular );
                    richTextBox1.AppendText( "\n" + func.Description + "\n\n" );
                    if ( func.Parameters.Count > 0 )
                    {
                        richTextBox1.SelectionFont = new Font( richTextBox1.SelectionFont, FontStyle.Bold );
                        richTextBox1.AppendText( "Parameters:" );
                        richTextBox1.SelectionFont = new Font( richTextBox1.SelectionFont, FontStyle.Regular );
                    }
                    foreach ( Parameter param in func.Parameters )
                    {
                        richTextBox1.SelectionFont = new Font( richTextBox1.SelectionFont, FontStyle.Italic );
                        richTextBox1.AppendText( "\n" + param.Name );
                        richTextBox1.SelectionFont = new Font( richTextBox1.SelectionFont, FontStyle.Regular );
                        richTextBox1.AppendText( ": " + param.Description );
                    }

                }
                else if ( memb is Property )
                {
                    Property prop = ( Property )memb;
                    richTextBox1.AppendText( prop.DataType + " " );
                    richTextBox1.SelectionFont = new Font( richTextBox1.SelectionFont, FontStyle.Bold );
                    richTextBox1.AppendText( lib.Name );
                    richTextBox1.SelectionFont = new Font( richTextBox1.SelectionFont, FontStyle.Regular );
                    richTextBox1.AppendText( "." );
                    richTextBox1.SelectionFont = new Font( richTextBox1.SelectionFont, FontStyle.Bold );
                    richTextBox1.AppendText( prop.Name );
                    richTextBox1.SelectionFont = new Font( richTextBox1.SelectionFont, FontStyle.Regular );
                    richTextBox1.AppendText( "\n\n" );
                    richTextBox1.SelectionFont = new Font( richTextBox1.SelectionFont, FontStyle.Bold );
                    richTextBox1.AppendText( "Summary:" );
                    richTextBox1.SelectionFont = new Font( richTextBox1.SelectionFont, FontStyle.Regular );
                    richTextBox1.AppendText( "\n" + prop.Description );
                }
            }
        }
        private void treeView2_AfterSelect( object sender, TreeViewEventArgs e )
        {
            if ( e.Node == null)
                return;

            LibraryMember lm = ( LibraryMember )e.Node.Tag;
            Library lib = lm.Library;
            Member memb = lm.Member;

            richTextBox1.Clear();

            if ( memb is Function )
            {
                Function func = ( Function )memb;
                richTextBox1.AppendText( func.Return + " " );
                richTextBox1.SelectionFont = new Font( richTextBox1.SelectionFont, FontStyle.Bold );
                richTextBox1.AppendText( func.Name );
                richTextBox1.SelectionFont = new Font( richTextBox1.SelectionFont, FontStyle.Regular );
                richTextBox1.AppendText( "(" );
                string paramText = "";
                foreach ( Parameter param in func.Parameters )
                {
                    paramText += param.DataType + " " + param.Name + ", ";
                }
                paramText = paramText.TrimEnd( ',', ' ' );
                richTextBox1.AppendText( paramText + ")\n\n" );
                richTextBox1.SelectionFont = new Font( richTextBox1.SelectionFont, FontStyle.Bold );
                richTextBox1.AppendText( "Summary:" );
                richTextBox1.SelectionFont = new Font( richTextBox1.SelectionFont, FontStyle.Regular );
                richTextBox1.AppendText( "\n" + func.Description + "\n\n" );
                if ( func.Parameters.Count > 0 )
                {
                    richTextBox1.SelectionFont = new Font( richTextBox1.SelectionFont, FontStyle.Bold );
                    richTextBox1.AppendText( "Parameters:" );
                    richTextBox1.SelectionFont = new Font( richTextBox1.SelectionFont, FontStyle.Regular );
                }
                foreach ( Parameter param in func.Parameters )
                {
                    richTextBox1.SelectionFont = new Font( richTextBox1.SelectionFont, FontStyle.Italic );
                    richTextBox1.AppendText( "\n" + param.Name );
                    richTextBox1.SelectionFont = new Font( richTextBox1.SelectionFont, FontStyle.Regular );
                    richTextBox1.AppendText( ": " + param.Description );
                }

            }
            else if ( memb is Property )
            {
                Property prop = ( Property )memb;
                richTextBox1.AppendText( prop.DataType + " " );
                richTextBox1.SelectionFont = new Font( richTextBox1.SelectionFont, FontStyle.Bold );
                richTextBox1.AppendText( lib.Name );
                richTextBox1.SelectionFont = new Font( richTextBox1.SelectionFont, FontStyle.Regular );
                richTextBox1.AppendText( "." );
                richTextBox1.SelectionFont = new Font( richTextBox1.SelectionFont, FontStyle.Bold );
                richTextBox1.AppendText( prop.Name );
                richTextBox1.SelectionFont = new Font( richTextBox1.SelectionFont, FontStyle.Regular );
                richTextBox1.AppendText( "\n\n" );
                richTextBox1.SelectionFont = new Font( richTextBox1.SelectionFont, FontStyle.Bold );
                richTextBox1.AppendText( "Summary:" );
                richTextBox1.SelectionFont = new Font( richTextBox1.SelectionFont, FontStyle.Regular );
                richTextBox1.AppendText( "\n" + prop.Description );
            }
        }

        private void toolStripButton1_Click( object sender, EventArgs e )
        {
            if (String.IsNullOrEmpty(toolStripComboBox1.Text))
                return;

            toolStripComboBox1.Items.Add( toolStripComboBox1.Text );

            treeView1.Nodes.Clear();
            treeView2.Nodes.Clear();

            foreach ( Library lib in code.Libraries )
            {
                if ( lib.Name.IndexOf( toolStripComboBox1.Text, 0, StringComparison.InvariantCultureIgnoreCase ) != -1 )
                {
                    TreeNode tn = new TreeNode();
                    tn.ImageKey = "library";
                    tn.SelectedImageKey = "library";
                    tn.Text = lib.Name;
                    tn.Tag = lib;
                    treeView1.Nodes.Add( tn );
                }
                foreach ( Member memb in lib.Members )
                {

                    if ( memb is Function )
                    {
                        LibraryMember lm = new LibraryMember();
                        lm.Library = lib;
                        lm.Member = memb;
                        Function func = ( Function )memb;

                        if ( func.Name.IndexOf( toolStripComboBox1.Text, 0, StringComparison.InvariantCultureIgnoreCase ) != -1 )
                        {

                            TreeNode tn = new TreeNode();
                            tn.Text = func.Name + "(" + func.Params + ")";
                            tn.Tag = lm;
                            switch ( func.Type )
                            {
                                case "SHARED":
                                    tn.ImageKey = "shared";
                                    tn.SelectedImageKey = "shared";
                                    break;
                                case "SERVER":
                                    tn.ImageKey = "server";
                                    tn.SelectedImageKey = "server";
                                    break;
                                case "CLIENT":
                                    tn.ImageKey = "client";
                                    tn.SelectedImageKey = "client";
                                    break;
                            }
                            treeView1.Nodes.Add( tn );
                        }
                    }
                    else if ( memb is Property )
                    {
                        LibraryMember lm = new LibraryMember();
                        lm.Library = lib;
                        lm.Member = memb;
                        Property prop = ( Property )memb;
                        if ( prop.Name.IndexOf( toolStripComboBox1.Text, 0, StringComparison.InvariantCultureIgnoreCase ) != -1 )
                        {
                            TreeNode tn = new TreeNode();
                            tn.Text = prop.Name;
                            tn.Tag = lm;
                            switch ( prop.Type )
                            {
                                case "SHARED":
                                    tn.ImageKey = "shared";
                                    tn.SelectedImageKey = "shared";
                                    break;
                                case "SERVER":
                                    tn.ImageKey = "server";
                                    tn.SelectedImageKey = "server";
                                    break;
                                case "CLIENT":
                                    tn.ImageKey = "client";
                                    tn.SelectedImageKey = "client";
                                    break;
                            }
                            treeView1.Nodes.Add( tn );
                        }
                    }
                }
            }
        }
        private void toolStripButton2_Click( object sender, EventArgs e )
        {
            toolStripComboBox1.Text = "<Search>";
            treeView2.Nodes.Clear();
            LoadLibs( code );
        }

        private void toolStripComboBox1_KeyDown( object sender, KeyEventArgs e )
        {
            if ( e.KeyCode == Keys.Enter )
                toolStripButton1_Click( null, null );
        }
        private void toolStripComboBox1_TextChanged( object sender, EventArgs e )
        {
            if ( toolStripComboBox1.Text == "<Search>" )
            {
                toolStripButton1.Enabled = false;
            }
            else
            {
                toolStripButton1.Enabled = true;
            }
        }
    }
    public class LibraryMember
    {
        public Library Library;
        public Member Member;
    }
}
